#include "shoppingcartdialog.h"
#include <QTableWidget>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QHeaderView>
#include <QMessageBox>
#include <QDebug>
#include <ctime> // For time()

// Include C backend headers
extern "C" {
#include "../backend/drink.h"
#include "../backend/order.h"
}

ShoppingCartDialog::ShoppingCartDialog(const QMap<int, int>& cartItems,
                                       int userId,
                                       DrinkNode* drinkList,
                                       QWidget *parent) :
    QDialog(parent),
    m_cartItems(cartItems),
    m_userId(userId),
    m_drinkListHead(drinkList), // Store pointer to drink list
    m_newOrdersHead(nullptr)
{
    setupUi();
    populateCartTable();
    calculateTotal();
}

ShoppingCartDialog::~ShoppingCartDialog()
{
    // Free the temporary new orders list if it wasn't saved/cleared
    if (m_newOrdersHead) {
        free_all_orders(m_newOrdersHead);
    }
    // Do NOT free m_drinkListHead here, it's owned by the caller (OrderingPanel)
}

void ShoppingCartDialog::setupUi()
{
    setWindowTitle("购物车");
    setMinimumWidth(500);

    // Table for cart items
    cartTable = new QTableWidget();
    cartTable->setColumnCount(4); // Name, Price, Quantity, Subtotal
    cartTable->setHorizontalHeaderLabels(QStringList() << "商品名称" << "单价" << "数量" << "小计");
    cartTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    cartTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
    cartTable->horizontalHeader()->setSectionResizeMode(2, QHeaderView::ResizeToContents);
    cartTable->horizontalHeader()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
    cartTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    // TODO: Optionally allow quantity changes in the cart table? Requires more logic.

    // Total price label
    totalPriceLabel = new QLabel("总计：￥ 0.00");
    totalPriceLabel->setObjectName("cartTotalLabel");
    totalPriceLabel->setStyleSheet("font-size: 16px; font-weight: bold;");

    // Buttons
    confirmButton = new QPushButton("✅ 确认下单");
    cancelButton = new QPushButton("❌ 取消");

    // Layouts
    QHBoxLayout *buttonLayout = new QHBoxLayout();
    buttonLayout->addStretch();
    buttonLayout->addWidget(cancelButton);
    buttonLayout->addWidget(confirmButton);

    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(new QLabel("请确认您的订单："));
    mainLayout->addWidget(cartTable);
    mainLayout->addWidget(totalPriceLabel, 0, Qt::AlignRight);
    mainLayout->addLayout(buttonLayout);

    // Connections
    connect(confirmButton, &QPushButton::clicked, this, &ShoppingCartDialog::handleConfirmOrder);
    connect(cancelButton, &QPushButton::clicked, this, &ShoppingCartDialog::reject); // Close dialog on cancel
}

void ShoppingCartDialog::populateCartTable()
{
    cartTable->setRowCount(0); // Clear existing rows
    if (!m_drinkListHead) {
        qWarning() << "Shopping cart cannot populate: Drink list is null.";
        return;
    }

    for (auto it = m_cartItems.constBegin(); it != m_cartItems.constEnd(); ++it) {
        int drinkId = it.key();
        int quantity = it.value();

        DrinkNode* drinkNode = find_drink_by_id(m_drinkListHead, drinkId);
        if (drinkNode) {
            int row = cartTable->rowCount();
            cartTable->insertRow(row);

            float price = drinkNode->data.price;
            float subtotal = price * quantity;

            cartTable->setItem(row, 0, new QTableWidgetItem(QString::fromUtf8(drinkNode->data.name)));
            cartTable->setItem(row, 1, new QTableWidgetItem(QString::number(price, 'f', 2)));
            cartTable->setItem(row, 2, new QTableWidgetItem(QString::number(quantity)));
            cartTable->setItem(row, 3, new QTableWidgetItem(QString::number(subtotal, 'f', 2)));
        } else {
            qWarning() << "Could not find drink details for ID:" << drinkId << "in shopping cart.";
            // Optionally add a row indicating missing item?
        }
    }
}

void ShoppingCartDialog::calculateTotal()
{
    m_totalPrice = 0.0f;
    if (!m_drinkListHead) return;

    for (auto it = m_cartItems.constBegin(); it != m_cartItems.constEnd(); ++it) {
        int drinkId = it.key();
        int quantity = it.value();
        DrinkNode* drinkNode = find_drink_by_id(m_drinkListHead, drinkId);
        if (drinkNode) {
            m_totalPrice += drinkNode->data.price * quantity;
        }
    }
    totalPriceLabel->setText(QString("总计：￥ %1").arg(m_totalPrice, 0, 'f', 2));
}

void ShoppingCartDialog::handleConfirmOrder()
{
    qDebug() << "Confirm order clicked. User ID:" << m_userId << "Items:" << m_cartItems;

    if (m_cartItems.isEmpty()) {
        QMessageBox::warning(this, "购物车为空", "您的购物车是空的，无法下单。");
        return;
    }

    if (!m_drinkListHead) {
         QMessageBox::critical(this, "错误", "无法获取饮品信息，请稍后重试。");
         return;
    }

    // --- 1. Check Stock ---
    for (auto it = m_cartItems.constBegin(); it != m_cartItems.constEnd(); ++it) {
        int drinkId = it.key();
        int quantity = it.value();
        DrinkNode* drinkNode = find_drink_by_id(m_drinkListHead, drinkId);
        if (!drinkNode) {
            QMessageBox::critical(this, "错误", QString("找不到商品 ID: %1 的信息。").arg(drinkId));
            return;
        }
        if (drinkNode->data.stock < quantity) {
            QMessageBox::warning(this, "库存不足", QString("商品 '%1' 库存不足 (仅剩 %2 份)。")
                                 .arg(QString::fromUtf8(drinkNode->data.name)).arg(drinkNode->data.stock));
            return;
        }
    }

    // --- 2. Load Existing Orders & Find Max ID ---
    OrderNode* existingOrdersHead = nullptr;
    int orderCount = load_orders("orders.dat", &existingOrdersHead); // Assuming "orders.dat"
    int nextOrderId = 1;
    if (orderCount > 0 && existingOrdersHead) {
        OrderNode* current = existingOrdersHead;
        while (current) {
            if (current->data.id >= nextOrderId) {
                nextOrderId = current->data.id + 1;
            }
            current = current->next;
        }
    } else if (orderCount < 0) {
         qWarning() << "Could not load orders.dat, starting order ID from 1.";
         // Allow proceeding, but log a warning
    }
    qDebug() << "Next Order ID will start from:" << nextOrderId;

    // --- 3. Create New Order Structs & Update Stock in Memory ---
    bool stockUpdateError = false;
    for (auto it = m_cartItems.constBegin(); it != m_cartItems.constEnd(); ++it) {
        int drinkId = it.key();
        int quantity = it.value();
        DrinkNode* drinkNode = find_drink_by_id(m_drinkListHead, drinkId); // Should exist based on stock check

        if (drinkNode) {
            // Create Order struct
            Order newOrderItem;
            newOrderItem.id = nextOrderId++; // Assign unique ID and increment
            newOrderItem.user_id = m_userId;
            newOrderItem.drink_id = drinkId;
            newOrderItem.quantity = quantity;
            newOrderItem.order_time = time(NULL);
            newOrderItem.status = ORDER_STATUS_PENDING; // Default status

            // Add order to the list in memory
            if (!add_order(&existingOrdersHead, &newOrderItem)) {
                 QMessageBox::critical(this, "错误", QString("无法添加订单项 (ID: %1)，请重试。").arg(newOrderItem.id));
                 free_all_orders(existingOrdersHead); // Clean up loaded orders
                 return;
            }

            // Update stock in memory (m_drinkListHead)
            Drink tempDrink = drinkNode->data; // Copy data
            tempDrink.stock -= quantity;       // Decrease stock
            if (!update_drink(m_drinkListHead, &tempDrink)) {
                qWarning() << "Failed to update stock in memory for drink ID:" << drinkId;
                stockUpdateError = true; // Mark error but continue adding orders for now
            }
        }
    }

    if (stockUpdateError) {
         QMessageBox::warning(this, "警告", "更新部分商品库存时遇到问题，但订单仍会尝试保存。");
         // Decide if you want to proceed or stop here
    }

    // --- 4. Save Orders & Drinks ---
    if (save_orders("orders.dat", existingOrdersHead) < 0) {
        QMessageBox::critical(this, "保存订单失败", "无法将订单保存到文件，请检查程序权限或磁盘空间。");
        free_all_orders(existingOrdersHead);
        // TODO: Should we revert stock changes in m_drinkListHead here? Difficult.
        return;
    }

    if (save_drinks("drinks.dat", m_drinkListHead) < 0) { // Assuming "drinks.dat"
        QMessageBox::warning(this, "保存库存失败", "订单已成功保存，但更新库存信息失败。请联系管理员。");
        // Order is placed, but stock might be inconsistent in the file
    }

    // --- 5. Success ---
    free_all_orders(existingOrdersHead); // Free the loaded/modified order list
    QMessageBox::information(this, "下单成功", "您的订单已成功提交！");
    emit orderPlacedSuccessfully(); // Notify OrderingPanel
    this->accept(); // Close the dialog
}